package com.ics.cmsadmin.modules.system.service.impl;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.PutObjectRequest;
import com.ics.cmsadmin.frame.property.AliOssConfig;
import com.ics.cmsadmin.modules.system.service.UploadService;
import com.ics.cmsadmin.frame.utils.CalendarUtil;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * Created by Sandwich on 2018-07-13
 */
@Service
@Log4j2
public class UploadServiceImpl implements UploadService {

    @Autowired
    private AliOssConfig aliOssConfig;
    private static String https = "https://";

    public Map uploadImage(MultipartFile file) throws Exception{
        // 获取文件名
        String fileName = file.getOriginalFilename();
        return toUploadImage(file, fileName,aliOssConfig.imagePath);
    }

    public Map uploadFile(MultipartFile file) throws Exception{
        // 获取文件名
        String fileName = file.getOriginalFilename();
        return toUploadImage(file, fileName,aliOssConfig.commonPath);
    }

    public Map uploadRenameImage(MultipartFile file) throws Exception{
        String fileName = getNewFileName(file);

        return toUploadImage(file, fileName,aliOssConfig.imagePath);
    }

    public String getNewFileName(MultipartFile file) {
        // 获取文件名
        String fileName = file.getOriginalFilename();
        // 获取文件的后缀名
        String suffixName = fileName.substring(fileName.lastIndexOf("."));
        String dateStr = CalendarUtil.dateToStr(new Date(), CalendarUtil.TimeFormat.yyyyMMdd);
        fileName = dateStr + "_" + UUID.randomUUID() + suffixName;
        return fileName;
    }

    public Map uploadRenameFile(MultipartFile file) throws Exception{
        // 获取文件名
        String fileName = getNewFileName(file);
        return toUploadImage(file, fileName,aliOssConfig.commonPath);
    }

    public Map toUploadImage(MultipartFile file, String fileName, String filePath) throws IOException {
        Map<String,Object> map = new HashMap();
        Boolean result = true;
        OSSClient ossClient = new OSSClient(https+aliOssConfig.endpoint, aliOssConfig.accessKeyId, aliOssConfig.accessKeySecret);
        try {
            InputStream is = file.getInputStream();
            log.info("Uploading a new object to OSS from a file");
            ossClient.putObject(new PutObjectRequest(aliOssConfig.bucketName, filePath+fileName, is));
        }catch (OSSException oe) {
            log.error("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            log.error("Error Message: " + oe.getErrorCode());
            log.error("Error Code:       " + oe.getErrorCode());
            log.error("Request ID:      " + oe.getRequestId());
            log.error("Host ID:           " + oe.getHostId());
            result = false;
        } catch (ClientException ce) {
            log.error("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            log.error("Error Message: " + ce.getMessage());
            result =  false;
        } finally {
            ossClient.shutdown();
        }
        map.put("result",result);
        if (result){
            String data =  https+aliOssConfig.bucketName+"."+aliOssConfig.endpoint+"/"+filePath+fileName;
            map.put("data",data);
        }
        return map;
    }

    public boolean deleteUploadedFile(String key) {
        OSSClient ossClient = new OSSClient(https+aliOssConfig.endpoint, aliOssConfig.accessKeyId, aliOssConfig.accessKeySecret);
        boolean success = true;
        try {
            ossClient.deleteObject(aliOssConfig.bucketName, key);
        } catch (OSSException | ClientException e) {
            success = false;
            e.printStackTrace();
        }
        return success;
    }

    public boolean deleteUploadedImageByFileName(String fileName) {
        return deleteUploadedFile(aliOssConfig.imagePath + fileName);
    }

    public boolean deleteUploadedImageByUrl(String url) {
        String fileName = url.substring(url.lastIndexOf("/") + 1);
        return deleteUploadedImageByFileName(fileName);
    }
}
